package com.cnfangmao.masterdata.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.cnfangmao.masterdata.common._enum.BasicDataRightEnum;
import com.cnfangmao.masterdata.common._enum.IsSelectFieldEnum;
import com.cnfangmao.masterdata.common._enum.MasterDataOperationTypeEnum;
import com.cnfangmao.masterdata.common._enum.MasterDataStoragePeriodEnum;
import com.cnfangmao.masterdata.common._enum.OrderByEnum;
import com.cnfangmao.masterdata.common.constant.Constant;
import com.cnfangmao.masterdata.common.util.ModelUtils;
import com.cnfangmao.masterdata.common.util.SnowFlakeUtils;
import com.cnfangmao.masterdata.dto.PageDto;
import com.cnfangmao.masterdata.model.BasicDataFieldMetadata;
import com.cnfangmao.masterdata.model.BasicDataStage;
import com.cnfangmao.masterdata.service.StageMasterDataManagerService;
import com.cnfangmao.masterdata.vo.MasterDataListPageVo;

/**
 * @description: TODO
 * @author: chenxc
 * @date: 2020年4月22日 下午12:34:08
 */
@Service(Constant.STAGE_MASTERDATA_STORAGE_ENGINE)
public class StageMasterDataManagerServiceImplWithMongodb extends MasterDataManagerServiceImplWithMongodb
		implements StageMasterDataManagerService {
	/**
	 * @description: TODO
	 * @author: chenxc
	 * @date: 2020年4月22日 下午12:30:04
	 * @param metadataId
	 * @param userId
	 * @param saveData
	 * @return
	 * @throws Exception 
	 * @see com.cnfangmao.masterdata.service.MasterDataManagerService#insert(java.lang.String,
	 *      java.lang.String, java.util.Map)
	 */
	@Override
	public boolean insert(String metadataId, String userId, Map<String, Object> saveData) throws Exception {
		
		if(saveData == null || saveData.size() == 0){
			throw new IllegalArgumentException("参数 saveData 为空");
		}
		
		// 检验当前账号是否拥有指定主数据的新增权限
		if(!this.rightService.checkPermissionByAccountBasicDataRight(userId, metadataId, BasicDataRightEnum.NEW.getCode())){
			throw new VerifyError("当前账号没有该主数据的新增权限");
		}
		
		// 校验字段规则
		if(!this.fieldService.checkField(userId, metadataId, saveData)){
			throw new VerifyError("字段规则校验不通过");	
		}
		
		BasicDataStage entity = new BasicDataStage();
		
		String key = SnowFlakeUtils.generator();
		entity.set__sys_stage_id(key);
		entity.set__sys_metadata_id(metadataId);
		entity.set__sys_instance_id(key);
		
		entity.set__sys_status(MasterDataOperationTypeEnum.ADD.getValue());
		
		Map<String, Object> map = ModelUtils.objectToMap(entity);
		
		// 合并具体的业务主数据实例数据
		map.putAll(saveData);
		
		return this.storage.insert(map, Constant.STAGE_MASTERDATA_STORAGE_TABLENAME);
	}

	/**
	 * @description: TODO
	 * @author: chenxc
	 * @date: 2020年4月22日 下午12:30:04
	 * @param metadataId
	 * @param userId
	 * @param saveData
	 * @param filterColumnMap
	 * @return
	 * @see com.cnfangmao.masterdata.service.MasterDataManagerService#update(java.lang.String,
	 *      java.lang.String, java.util.Map, java.util.Map)
	 */
	@Override
	public boolean update(String metadataId, String userId, Map<String, Object> saveData, Map<String, Object> filterColumnMap) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * @description: TODO
	 * @author: chenxc
	 * @date: 2020年4月22日 下午12:30:04
	 * @param metadataId
	 * @param userId
	 * @param filterColumnMap
	 * @return
	 * @see com.cnfangmao.masterdata.service.MasterDataManagerService#delete(java.lang.String,
	 *      java.lang.String, java.util.Map)
	 */
	@Override
	public boolean delete(String metadataId, String userId, Map<String, Object> filterColumnMap) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * @description: TODO
	 * @author: chenxc
	 * @date: 2020年4月22日 下午12:34:47
	 * @param metadataId
	 * @param userId
	 * @param lstMergeId
	 * @return
	 * @see com.cnfangmao.masterdata.service.StageMasterDataManagerService#unMerge(java.lang.String,
	 *      java.lang.String, java.util.List)
	 */
	@Override
	public boolean unMerge(String metadataId, String userId, List<String> lstMergeId) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * @description: TODO
	 * @author: chenxc
	 * @date: 2020年4月22日 下午12:34:47
	 * @param metadataId
	 * @param userId
	 * @param lstMasterDataId
	 * @return
	 * @see com.cnfangmao.masterdata.service.StageMasterDataManagerService#publish(java.lang.String,
	 *      java.lang.String, java.util.List)
	 */
	@Override
	public boolean publish(String metadataId, String userId, List<String> lstMasterDataId) {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * @description: 重写子类的findPage，指定当前查询是临时存储区查询
	 * @author: chenxc
	 * @date: 2020年4月24日 上午10:51:36
	 * @param metadataId
	 * @param userId
	 * @param page
	 * @param filterColumnMap
	 * @param selectColumnMap
	 * @param orderColumnMap
	 * @return   
	 * @see com.cnfangmao.masterdata.service.impl.MasterDataManagerServiceImplWithMongodb#findPage(java.lang.String, java.lang.String, com.cnfangmao.masterdata.dto.PageDto, java.util.Map)
	 */
	@Override
	public MasterDataListPageVo findPage(String metadataId, String userId, PageDto page, Map<String, Object> filterColumnMap, Map<String, IsSelectFieldEnum> selectColumnMap, Map<String, OrderByEnum> orderColumnMap) {
		this.period = MasterDataStoragePeriodEnum.STAGE;
		return super.findPage(metadataId, userId, page, filterColumnMap, selectColumnMap, orderColumnMap);
	}
	
	/**
	 * @description: 因为只有这一层才能具体知道查询Map的结构，因此重写子类生成Query的方法 
	 * @author: chenxc
	 * @date: 2020年4月24日 上午10:53:32
	 * @param filterColumnMap
	 * @param paramMap
	 * @return   
	 * @see com.cnfangmao.masterdata.service.impl.MasterDataManagerServiceImplWithMongodb#getQuery(java.util.Map, java.util.Map)
	 */
	@Override
	protected Query getQuery(Map<String, Object> filterColumnMap, Map<String, Object> paramMap){
		Query query = new Query();
		
		// 首先添加根据元数据id来查询
		if(paramMap != null && paramMap.containsKey("p_metadata_id")){
			query.addCriteria(Criteria.where("__sys_metadata_id").is(paramMap.get("p_metadata_id")));
		}
		
		if(filterColumnMap == null || filterColumnMap.size() == 0){
			return query;
		}
		
		Set<String> lstFieldCode = new HashSet<String>();
		
		// 子类对应的调用方法会构造paramMap，将需要的参数传递过来，在该调用过程中，p_field_list代表字段元数据列表
		if(paramMap != null && paramMap.containsKey("p_field_list")){
			@SuppressWarnings("unchecked")
			List<BasicDataFieldMetadata> lstField = (List<BasicDataFieldMetadata>) paramMap.get("p_field_list");
			
			Map<String, BasicDataFieldMetadata> mapField = this.getMapFromListBasicDataFieldMetadata(lstField);
			
			// 获取所有字段code集合
			lstFieldCode = mapField.keySet();
		}
		
		for (Map.Entry<String, Object> item : filterColumnMap.entrySet()) {
			String fieldCode = item.getKey();
			// 过滤掉不合法的查询类型及字段
			if(!this.checkValidQueryField(lstFieldCode, fieldCode)){
				continue;
			}
			
			// 所有主数据实例都是放在根文档目录中，因此不需要指定前缀（即：文档的前面路径）
			query.addCriteria(this.getCriteria(fieldCode, "", "", item.getValue()));
		}
		
		return query;
	}
}
